import { useStorage } from '@vueuse/core'
import { acceptHMRUpdate, defineStore, storeToRefs } from 'pinia'
import { ref } from 'vue'

import router from '@/router'
import { resolveMenu, resolveRoute } from '@/router/helper'
import { routeRecordRaw } from '@/router/record'

import { pinia } from '.'

import type { MenuMixedOptions, MenuOption, MenuGroup } from '@/router/helper'
import type { MenuProps } from 'naive-ui'
import type { RouteRecordRaw } from 'vue-router'

interface User {
  avatar?: string
  id?: string
  name?: string
  username?: string
  email?: string
  role?: 'admin' | 'user' | 'tenant'
  permissions?: number[]
  createdAt?: string
  updatedAt?: string
}

const DEFAULT_USER: User = {
  avatar: '',
  id: '',
  name: '',
  username: '',
  email: '',
  role: 'user',
  permissions: [],
  createdAt: '',
  updatedAt: '',
}

export const useUserStore = defineStore('userStore', () => {
  const user = useStorage<User>('user', DEFAULT_USER)

  const token = useStorage<string | null>('token', null)

  const menuList = ref<MenuProps['options']>([])

  const routeList = ref<RouteRecordRaw[]>([])

  async function resolveMenuRoute() {
    const res = await new Promise<MenuMixedOptions[]>((resolve) => {
      // 过滤有权限的菜单
      const filterMenu = (routes: MenuMixedOptions[]): MenuMixedOptions[] => {
        return routes.filter(route => {
          // 跳过分割线
          if (route.type === 'divider') {
            return true;
          }

          // 检查当前路由是否有权限配置
          if ((route as MenuOption).meta?.permissionId) {
            // 检查用户是否拥有该权限
            return user.value?.permissions?.includes((route as MenuOption).meta?.permissionId as number) ?? false
          }

          // 如果是分组或有子路由的菜单
          if ((!route.type || route.type === 'group')) {
            const menuItem = route as MenuOption | MenuGroup;
            if (Array.isArray(menuItem.children) && menuItem.children.length > 0) {
              // 递归过滤子路由
              menuItem.children = filterMenu(menuItem.children)
              // 如果有子路由通过过滤，则当前路由保留
              return menuItem.children.length > 0
            }
          }

          // 默认保留
          return true
        })
      }

      resolve(filterMenu(routeRecordRaw))
    })

    const resolvedMenu = resolveMenu(res) || []
    const resolvedRoute = resolveRoute(res) || []

    menuList.value = resolvedMenu
    routeList.value = resolvedRoute

    return {
      menuList: resolvedMenu,
      routeList: resolvedRoute,
    }
  }

  function cleanup(redirectPath?: string) {
    router.replace({
      name: 'signIn',
      ...(redirectPath ? { query: { r: redirectPath } } : {}),
    })

    token.value = null

    if (router.hasRoute('layout')) {
      router.removeRoute('layout')
    }

    menuList.value = []

    routeList.value = []
  }

  return {
    user,
    token,
    menuList,
    routeList,
    resolveMenuRoute,
    cleanup,
  }
})

export function toRefsUserStore() {
  return {
    ...storeToRefs(useUserStore(pinia)),
  }
}

if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot))
}
